#include "p11.h"
#include <iostream>


template<int N>
constexpr int factorial() {
    static_assert(N >= 0, "N < 0");

    int product {1};
    for (int i {2}; i <= N; ++i) {
        product *= i;
    }

    return product;
}

void testHomeWork11_09() {
    static_assert(factorial<0>() == 1, "NONONONO");
    static_assert(factorial<3>() == 6, "NONONONO");
    static_assert(factorial<5>() == 120, "NONONONO");

    // factorial<-3>();     // -3 trigger static_assert(N >= 0, "N < 0");
}

template <typename T>
T add(T x, T y) {
    return x + y;
}


void testHomeWork11_q2() {
    std::cout << add(2, 3) << '\n';
    std::cout << add(1.2, 3.4) << '\n';
}

template <typename T, typename U>
T mult(T x, U y) {
    return x * y;
}

void testHomeWork11_q3() {
    std::cout << mult(2, 3) << '\n';
    std::cout << mult(1.2, 3) << '\n';
}

template <typename T, typename U>
auto sub(T x, U y) {
    return x - y;
}

void testHomeWork11_q4() {
    std::cout << sub(3, 2) << '\n';
    std::cout << sub(3.5, 2) << '\n';
    std::cout << sub(4, 1.5) << '\n';
}

template <typename T>
int foo(T n) {
    return n;
}

template <typename T>
int count(T) {
    static int c {0};
    return ++c;
}

int foo(int n) {
    return n + 10;
}

void testHomeWork11_last() {
    std::cout << "Input: " << 1 << ", Res = "<< count(1) << '\n';
    std::cout << "Input: " << 1 << ", Res = "<< count(1) << '\n';
    std::cout << "Input: " << 1 << ", Res = "<< count(2.3) << '\n';
    std::cout << "Input: " << 1 << ", Res = "<< count<double>(1) << '\n';

    std::cout << "Test foo(1), " << "Res = "<< foo(1) << '\n';
    std::cout << "Test foo<int>(4), " << "Res = "<< foo<int>(4) << '\n';
    std::cout << "Test foo<int>(5), " << "Res = "<< foo<int>(5) << '\n';
    std::cout << "Test foo<>(6), " << "Res = "<< foo<>(6) << '\n';
}
